﻿using System;

namespace BoCaiWeb.Model
{
    /// <summary>
    /// Base for all business objects.
    /// </summary>
    /// <typeparam name="T">DataType of the primary key.</typeparam>
    [Serializable]
    public abstract class ModelBase<T> : IModelBase<T>, ICloneable//, IComparable
    {
        #region Declarations

        private T _id = default(T);

        #endregion

        #region Methods
        public abstract override int GetHashCode();

        public override bool Equals(object obj)
        {
            return (obj != null)                                                    // 1) Object is not null.
                && (obj.GetType() == this.GetType())                                // 2) Object is of same Type.
                && (MatchingIds((ModelBase<T>)obj) || MatchingHashCodes(obj));      // 3) Ids or Hashcodes match.
        }
        protected virtual bool MatchingIds(ModelBase<T> obj)
        {
            return (this.Id != null && !this.Id.Equals(default(T)))                 // 1) this.Id is not null/default.
                && (obj.Id != null && !obj.Id.Equals(default(T)))                   // 1.5) obj.Id is not null/default.
                && (this.Id.Equals(obj.Id));                                        // 2) Ids match.
        }
        protected virtual bool MatchingHashCodes(object obj)
        {
            return this.GetHashCode().Equals(obj.GetHashCode());                    // 1) Hashcodes match.
        }

        #endregion

        #region Properties
        /// <summary>
        /// ID
        /// </summary>
        public virtual T Id
        {
            get { return _id; }
            set { _id = value; }
        }

        #endregion

        #region ICloneable 成员

        public virtual object Clone()
        {
            return this.MemberwiseClone();
        }

        #endregion

        #region IComparable 成员

        //public virtual int CompareTo(object obj)
        //{
        //    if ((this == null) && (obj == null))
        //    {
        //        return 0;
        //    }
        //    else if ((this != null) && (obj == null))
        //    {
        //        return 1;
        //    }
        //    else if ((this == null) && (obj != null))
        //    {
        //        return -1;
        //    }

        //    return (new System.Collections.CaseInsensitiveComparer()).Compare(this, obj);
        //}

        #endregion
    }
}
